use serde::{Deserialize, Serialize};
use std::fs;
use std::path::Path;
use uuid::Uuid;
use chrono::{DateTime, Utc};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum ModelPriority {
    Low,
    Medium,
    High,
}

impl Default for ModelPriority {
    fn default() -> Self {
        ModelPriority::Medium
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelTodoItem {
    pub id: String,
    pub title: String,
    pub completed: bool,
    pub priority: ModelPriority,
    pub due_date: Option<DateTime<Utc>>,
}

pub struct TodoManager {
    todos: Vec<ModelTodoItem>,
    file_path: String,
}

impl TodoManager {
    pub fn new(file_path: &str) -> Self {
        let todos = if Path::new(file_path).exists() {
            match fs::read_to_string(file_path) {
                Ok(data) => match serde_json::from_str(&data) {
                    Ok(parsed_todos) => parsed_todos,
                    Err(_) => Vec::new(),
                },
                Err(_) => Vec::new(),
            }
        } else {
            Vec::new()
        };

        Self {
            todos,
            file_path: file_path.to_string(),
        }
    }

    pub fn get_todos(&self) -> &Vec<ModelTodoItem> {
        &self.todos
    }

    pub fn add_todo(&mut self, title: &str, priority: ModelPriority) -> ModelTodoItem {
        let new_todo = ModelTodoItem {
            id: Uuid::new_v4().to_string(),
            title: title.to_string(),
            completed: false,
            priority,
            due_date: None,
        };

        self.todos.push(new_todo.clone());
        self.save_to_file();
        new_todo
    }

    pub fn toggle_todo(&mut self, id: &str) -> bool {
        if let Some(todo) = self.todos.iter_mut().find(|t| t.id == id) {
            todo.completed = !todo.completed;
            self.save_to_file();
            true
        } else {
            false
        }
    }

    pub fn edit_todo(&mut self, id: &str, new_title: &str) -> bool {
        if let Some(todo) = self.todos.iter_mut().find(|t| t.id == id) {
            todo.title = new_title.to_string();
            self.save_to_file();
            true
        } else {
            false
        }
    }

    pub fn set_priority(&mut self, id: &str, priority: ModelPriority) -> bool {
        if let Some(todo) = self.todos.iter_mut().find(|t| t.id == id) {
            todo.priority = priority;
            self.save_to_file();
            true
        } else {
            false
        }
    }

    pub fn set_due_date(&mut self, id: &str, due_date: Option<DateTime<Utc>>) -> bool {
        if let Some(todo) = self.todos.iter_mut().find(|t| t.id == id) {
            todo.due_date = due_date;
            self.save_to_file();
            true
        } else {
            false
        }
    }

    pub fn delete_todo(&mut self, id: &str) -> bool {
        let initial_len = self.todos.len();
        self.todos.retain(|todo| todo.id != id);
        
        if self.todos.len() != initial_len {
            self.save_to_file();
            true
        } else {
            false
        }
    }

    fn save_to_file(&self) {
        if let Ok(json) = serde_json::to_string(&self.todos) {
            let _ = fs::write(&self.file_path, json);
        }
    }
} 